<?php
/**
*
*	后台数据库管理 @zairwolf
*	2009-4-25 import时候存在问题，现在导入的是sql不是文件 13:06 
*/
if(!defined('IN_ACP')) exit('Access Denied');

//安全运行文件
define('SITE_SAFE_SQL', ROOT."data/sql.run");
$sqlrun = is_file(SITE_SAFE_SQL);
$sqlsff = substr(SITE_SAFE_SQL, strlen(ROOT));


if(!$action) {
	if(in_array($pfile, array('dbexport', 'dbimport', 'dbupdate', 'dboptimize', 'dbrepair'))) $action=$pfile;
}

//禁止运行sql
if($action == 'disable') {
	if(!$sqlrun) b('已禁止运行 SQL');

	if(!unlink(SITE_SAFE_SQL)) b('删除安全文件 '.$sqlsff.' 失败，请从ftp手动删除');

	j("?ptype=$ptype&pfile=$pfile", '禁止 SQL 运行成功');
}

//运行sql
if($action == 'execsql') {
	$queries=_post('queries');
	if(!$sqlrun) b('当前不可运行 SQL 语句，请从ftp创建 '.$sqlsff.' 文件');
	if(!empty($queries)) $queries = trim($queries);
	if(empty($queries)) b('请输入要运行的 SQL 语句');

	$sqls = split_sql(stripslashes($queries));
	foreach($sqls as $sql) {
		db_q($sql);
	}

	j("?ptype=$ptype&pfile=$pfile", '运行成功');
}

//运行sql
if($action == 'dbupdate') {
	$tpl = new T($ptype.'_'.$pfile);
	$tpl->assign(array(
		'queries' => empty($queries) ? '' : html_show($queries, false),
		'sqlrun' => $sqlrun,
		'sqlsff' => $sqlsff,
	));
	$tpl->output();
}

//优化运行
if($action == 'optimize') {
	$tbl_r8=_post('tbl_r8');
	if(empty($tbl_r8) || !is_array($tbl_r8)) b('请选择要优化的数据表');
	db_q('REPAIR TABLE `'.implode('`, `', $tbl_r8).'`');
	j("?ptype=$ptype&pfile=$pfile", '数据库优化成功');
}

//优化显示
if($action == 'dboptimize') {
	$r8_tables = db_rows("SHOW TABLE STATUS WHERE Name LIKE '$db_prefix%'");
	$other_tables = db_rows("SHOW TABLE STATUS WHERE Name NOT LIKE '$db_prefix%'");
	foreach($r8_tables as $k => $v) {
		$r8_tables[$k]['Data_length']  = sizecount($v['Data_length'],  true);
		$r8_tables[$k]['Index_length'] = sizecount($v['Index_length'], true);
		$r8_tables[$k]['Data_free']    = sizecount($v['Data_free'],    true);
	}
	foreach($other_tables as $k => $v) {
		$other_tables[$k]['Data_length']  = sizecount($v['Data_length'],  true);
		$other_tables[$k]['Index_length'] = sizecount($v['Index_length'], true);
		$other_tables[$k]['Data_free']    = sizecount($v['Data_free'],    true);
	}

	//显示
	$tpl = new T($ptype.'_'.$pfile);
	$tpl->assign(array(
		'db_prefix' => $db_prefix,
		'list' => $r8_tables,
		'other_tables' => $other_tables,
	));
	$tpl->output();
}

//输出处理
if($action == 'exportdo') {
	$tbl_r8=_post('tbl_r8');
	$file=_post('file');
	$tables=_post('tables');
	$compress=_post('compress');
	if(empty($tbl_r8) || !is_array($tbl_r8)) b('请选择要备份的数据表');
	if(empty($file) || !preg_match('/^[A-Za-z0-9_]+$/', $file)) b('文件名只能用数字，英文字母和下划线');
	if(empty($tables) || !in_array($tables, array('full', 'novel', 'user', 'config', 'custom'))) $tables = 'custom';
	if(empty($compress) || !in_array($compress, array('none', 'zip', 'gzip', 'bzip'))) $compress = 'none';
	switch($compress) {//压缩处理
		case 'zip':
			if(function_exists('gzcompress')) {
				$file_ext = 'zip';
			}else {
				$compress = 'none';
				$file_ext = 'sql';
			}
			break;
		case 'gzip':
			if(function_exists('gzencode')) {
				$file_ext = 'tar.gz';
			}else {
				$compress = 'none';
				$file_ext = 'sql';
			}
			break;
		case 'bzip':
			if(function_exists('bzcompress')) {
				$file_ext = 'tar.bz2';
			}else {
				$compress = 'none';
				$file_ext = 'sql';
			}
			break;
		default :
			$compress = 'none';
			$file_ext = 'sql';
			break;
	}

	$f = ROOT.'data/backup/'.$file.'.sql';

	cookie('tables',   $tables,   864000);
	cookie('compress', $compress, 864000);

	$data = '# database '.$tables.' dump'."\n".
			'# Identify:    '.base64_encode($tables.','.TIMESTAMP)."\n".
			'# MySQL:       '.db_ver()."\n".
			'# PHP:         '.PHP_VERSION."\n".
			'# Export Date: '.rdate(TIMESTAMP)."\n".
			'# ----------------------------------------------------------'."\n\n\n\n".
	write($f, $data);

	$length = rmb_strlen($data);
	foreach($tbl_r8 as $tbl) {
		$tbl_info = db_rows('SHOW CREATE TABLE '.$tbl);
		$sql =  "\n-- --------------------------------------------------------\n\n--\n".
				'-- `'.$tbl.'` 的结构'."\n--\n\n".
				'DROP TABLE IF EXISTS `'.$tbl.'`;'."\n".
				$tbl_info[0]['Create Table'].';'."\n".
				"\n--\n--`$tbl` 的数据\n--\n\n";
		$length += rmb_strlen($sql);
		write($f, $sql);

		$page = 1;
		while(1) {
			set_time_limit(60);

			$data = db_rows("select * from $tbl limit 100");exit('以下未整理');
			$db->select(array(
				'from'  => 3,
				'limit' => 100,
				'page'  => $page,
				'counter'=>true,
			));

			foreach($data as $v) {
				$sql = str_replace(array("\r", "\n"), array('\r', '\n'), $db->insert(_addslashes($v), $tbl)).';'."\n";
				$length += rmb_strlen($sql);
				write($f, $sql);
			}

			$page++;
			if(ceil($db->counter / 100) < $page)
				break;
		}
	}

	if($compress != 'none') {
		require_once ROOT.'include/Archive.class.php';

		$archive_class = $compress.'_file';
		$archive = new $archive_class($file.'.'.$file_ext);
		$archive->set_options(array(
			'basedir' => ROOT.'data/backup',
		));
		$archive->add_files($file.'.sql');
		$archive->create_archive();
		unlink($f);
	}

	j("?ptype=$ptype&pfile=$pfile", '数据库备份成功');
}

//输出界面显示
if($action == 'dbexport') {
	$export_tables = _cookie('tables');
	if(!$export_tables) $export_tables = 'full';
	$compress = _cookie('compress');
	switch($compress) {
		case 'zip':
			if(function_exists('gzcompress')) {
				$file_ext = 'zip';
			}else {
				$compress = 'none';
				$file_ext = 'sql';
			}
			break;
		case 'gzip':
			if(function_exists('gzencode')) {
				$file_ext = 'tar.gz';
			}else {
				$compress = 'none';
				$file_ext = 'sql';
			}
			break;
		case 'bzip':
			if(function_exists('bzcompress')) {
				$file_ext = 'tar.bz2';
			}else {
				$compress = 'none';
				$file_ext = 'sql';
			}
			break;
		default :
			$compress = 'none';
			$file_ext = 'sql';
			break;
	}

	$r8_tables = db_rows("SHOW TABLE STATUS WHERE Name LIKE '$db_prefix%'");
	$other_tables = db_rows("SHOW TABLE STATUS WHERE Name NOT LIKE '$db_prefix%'");
	foreach($r8_tables as $k => $v) {
		$r8_tables[$k]['Data_length']  = sizecount($v['Data_length'],  true);
		$r8_tables[$k]['Index_length'] = sizecount($v['Index_length'], true);
		$r8_tables[$k]['Data_free']    = sizecount($v['Data_free'],    true);
	}
	foreach($other_tables as $k => $v) {
		$other_tables[$k]['Data_length']  = sizecount($v['Data_length'],  true);
		$other_tables[$k]['Index_length'] = sizecount($v['Index_length'], true);
		$other_tables[$k]['Data_free']    = sizecount($v['Data_free'],    true);
	}

	//显示
	$tpl = new T($ptype.'_'.$pfile);
	$tpl->assign(array(
		'export_tables' => $export_tables,
		'tables_full'   => $export_tables == 'full'   ? ' checked="checked"' : '',
		'tables_novel'  => $export_tables == 'novel'  ? ' checked="checked"' : '',
		'tables_user'   => $export_tables == 'user'   ? ' checked="checked"' : '',
		'tables_config' => $export_tables == 'config' ? ' checked="checked"' : '',
		'tables_custom' => $export_tables == 'custom' ? ' checked="checked"' : '',

		'compress_none' => $compress == 'none' ? ' checked="checked"' : '',
		'compress_zip'  => function_exists('gzcompress') ? ($compress == 'zip'  ? ' checked="checked"' : '') : ' disabled="disabled"',
		'compress_gzip' => function_exists('gzencode')   ? ($compress == 'gzip' ? ' checked="checked"' : '') : ' disabled="disabled"',
		'compress_bzip' => function_exists('bzcompress') ? ($compress == 'bzip' ? ' checked="checked"' : '') : ' disabled="disabled"',

		'db_prefix' => $db_prefix,

		'C_file'   => rdate(TIMESTAMP, 'ymd').'_'.rrand(8, 7),
		'file_ext' => $file_ext,

		'r8_tables' => $r8_tables,
		'other_tables' => $other_tables,
	));
	$tpl->output();
}

//文件导入
if($action == 'importdo') {//奇怪，不是导入文件吗？怎么成了sql 2009-4-25 12:59 @zairwolf
	$queries=_get('queries');
	if(!$sqlrun) b('当前不可运行 SQL 语句，请从ftp创建 '.$sqlsff.' 文件');
	if(!empty($queries)) $queries = trim($queries);
	if(empty($queries)) b('请输入要运行的 SQL 语句');

	$sqls = split_sql(stripslashes($queries));
	foreach($sqls as $sql) {
		db_q($sql);
	}
	j("?ptype=$ptype&pfile=$pfile", '运行成功');
}

//删除备份文件
if($action == 'delete') {
	$unlinkfile=_post('unlinkfile');
	if(empty($unlinkfile) || !is_array($unlinkfile)) b('请选择要删除的文件');
	foreach($unlinkfile as $filename) {
		if(rfileext($filename) != 'sql') continue;
		if(!preg_match('/^[A-Za-z0-9_]+$/', substr($filename, 0, -4))) continue;
		unlink(ROOT.'data/backup/'.$filename);
	}
	j("?ptype=$ptype&pfile=$pfile", '删除成功');
}

//导入默认显示
if($action=='dbimport'){
	$files = array();
	foreach(rlistfile(ROOT.'data/backup') as $v) {
		if(rfileext($v) == 'sql') {
			$i = explode(',', base64_decode(rsubstr(file_get_contents(ROOT.'data/backup/'.$v), '# Identify:    ',"\n")));
			$files[] = array(
				'filename' => $v,
				'filesize' => sizecount(filesize(ROOT.'data/backup/'.$v)),
				'version'  => $i[1],
				'dateline' => $i[2],
				'tables'   => $i[0],
				'sqlrun'   => $sqlrun,
			);
		}
	}


	$tpl = new T($ptype.'_'.$pfile);
	$tpl->assign(array(
		'files' => $files,
		'sqlrun' => $sqlrun,
		'sqlsff' => $sqlsff,
	));
	$tpl->output();
}






//-----------------函数------------------//
//sql分割函数
function split_sql($sql){
	global $_SYSTEM;

	$sql = str_replace("\r", '', $sql);
	$sqls = array();
	foreach(explode(";\n", $sql) as $sql) {
		$sql = trim($sql);
		if(!$sql || $sql[0] == '#' || $sql[0] == '-')
			continue;

		$sqls[] = str_replace(array('\r', '\n', '`rd8_'), array("\r", "\n", '`'.$db_prefix), $sql);
	}
	return $sqls;
}

